home *** CD-ROM | disk | FTP | other *** search
- ;; cmode.mut : an electric C mode
-
- ;; Electric C mode is designed to help keep your C code formatted "as you
- ;; code". You don't have to remember anything special - as you type, what
- ;; you type is looked at and may trigger certain actions. This is a
- ;; minimalist C mode ment to enable you to keep your C code formatted in a
- ;; consistant manner. The only extensive help is for comments.
-
- ;; Characters that trigger formatting:
- ;; "{": When a "{" is pressed, one of the following will happen:
- ;; - If the space bar is pressed, "{ }" is generated and the cursor is
- ;; put between the braces.
- ;; - If Enter is pressed:
- ;; And the rest of the line is blank, you will get something like:
- ;; if (a) { or if (a)
- ;; cursor {
- ;; } cursor
- ;; }
- ;; depending on where the "{" was. The cursor is indented by the
- ;; amount specified by "INDENT-LEVEL".
- ;; If the rest of the line was not blank, a newline-and-indent is
- ;; done and the text after the { is indented.
- ;; For example:
- ;; if (a) foo(): if a "{ Enter" is done before the foo()
- ;; you will get:
- ;; if (a) {
- ;; foo()
- ;; - Otherwise, a "{" is inserted.
- ;; Backspace: Behaves like backspacing over spaces even when backspacing
- ;; over tabs.
- ;; Newline (control-J): Used to give some white space after a variable
- ;; declaration block. The cursor is left at the same column as the start
- ;; of the declarations.
- ;; int j; => int j;
- ;; blank line
- ;; cursor
- ;; "/": Comment assistance.
- ;; - If "*" is pressed and the rest of the line is blank and there is
- ;; text to the left of the "/", "/* */" is generated and the cursor
- ;; is put in the middle of the comment. This is for end of line
- ;; comments like: if (a) foobar(); /* comment */
- ;; - If "*" is pressed and the entire line is blank, block comment mode
- ;; is entered. In this mode, your comment will autowrap at the
- ;; COMMENT-WRAP-COLUMN. When you hit Enter or autowrap, stars are
- ;; put in the proper place, whitespace is added to match the
- ;; previous comment line. If you press Enter "/", comment mode will
- ;; terminate. "*/" or "*" blanks "/" will also terminate comment
- ;; mode. If you want to get out of comment mode without using the
- ;; above, press M-; or execute "nocomment".
- ;; Examples:
- ;; /*
- ;; * Comment
- ;; * Indented a bit
- ;; * Next line follows the indent.
- ;; */
- ;; /*
- ;; ** Another comment style
- ;; */
- ;; - Otherwise, a "/" is inserted.
- ;; Meta-;
- ;; If in block comment mode, turn off comment mode.
- ;; If the cursor is on a line that is part of a block comment, start up
- ;; block comment mode. This is very handy for adding to an existing
- ;; block comment.
- ;; Meta-J: Format a C block comment.
- ;; If you munge a block comment and want to set it right, use this.
- ;; This formats all the lines between the dot and mark inclusive.
- ;; Put the region around the comment (or the part of the comment you want
- ;; to format) and press M-J. The comment is commented in the format of
- ;; comment mode.
- ;; Notes:
- ;; To make sure that line breaks are preserved, insert blank lines at
- ;; the breaks. The blank lines will be deleted after the comment
- ;; is formatted.
- ;; To change the indent level of the block, indent the first line of
- ;; the region to where you want.
- ;; Control-U Meta-J: Format a C boxed comment.
- ;; Same as format block comment except the comment is boxed:
- ;; /********************************
- ;; * Comment *
- ;; ********************************/
- ;; You can convert between boxed and block comments by just reformatting.
-
- ;; C Durland Public Domain
-
-
- (const
- INDENT-LEVEL 2 ;; spaces to indent a {} block
- COMMENT-WRAP-COLUMN 76 ;; where to word wrap in comment mode
- TAB-SIZE 0 ;; 0 means use tabs else n spaces for each tab
-
- C-STARS " *" ;; comment body stars: " *" or "**".
- COMET " */" ;; comment end stars: " */" or "*/".
-
- ;; number of blank lines before and after text in boxed comment
- BOXED-COMMENT-SPACE 1 ;; blank lines between box and text
- BOXED-COMMENT-TRAILING-BLANKS 1 ;; blanks between text and *
- BOXED-COMMENT-EDGE-STARS "*" ;; right edge stars: "*" or "**"
-
- ENTER-KEY-ACTION "newline-and-indent" ;; newline-and-indent or newline
- )
-
- (int
- indent-level comment-wrap-column
- boxed-comment-space boxed-comment-trailing-blanks
- )
- (string c-stars comet boxed-comment-edge-stars enter-key-action)
-
- (include me2.h)
-
- (defun
- c-mode ; set up electric C mode
- {
- (clear-modes)
-
- (bind-local-key ENTER-KEY-ACTION "C-m")
- (bind-local-key "C-mode-{" "{")
- (bind-local-key "after-declare" "C-j")
- (bind-local-key "Dr.commento" "/")
- (bind-local-key "BS-untabify" "C-h")
- (bind-local-key "format-C-comment" "M-j")
- (bind-local-key "Nurse-commento" "M-;")
-
- (create-buffer-var NUMBER "comment-offset")
-
- (major-mode "C")
-
- (tab-stops TAB-SIZE)
- (c-mode-etc INDENT-LEVEL COMMENT-WRAP-COLUMN C-STARS COMET)
- (c-mode-boxed BOXED-COMMENT-SPACE BOXED-COMMENT-TRAILING-BLANKS
- BOXED-COMMENT-EDGE-STARS)
-
- (if (pgm-exists "c-mode-hook") (floc "c-mode-hook"()))
-
- (enter-key-action (key-bound-to "C-m"))
- }
- c-mode-etc (int indent comment-wrap) (string stars comets)
- {
- (indent-level indent)
- (comment-wrap-column comment-wrap)
- (c-stars stars)
- (comet comets)
- }
- c-mode-boxed (int comment-space trailing-blanks) (string edge-stars)
- {
- (boxed-comment-space comment-space)
- (boxed-comment-trailing-blanks trailing-blanks)
- (boxed-comment-edge-stars edge-stars)
- }
- )
-
- (include bs_untab.mut)
- (include block.mut)
-
- (defun
- "C-mode-{" ; handle {
- {
- (int key n)
-
- (insert-text "{")(update)
- (switch (key (get-key))
- Space-bar ; try for { . } else just insert a blank
- {
- (if (looking-at '\ *$') ; only whitespace 'til end of line
- { (insert-text " }")(previous-character)(previous-character) }
- (insert-text " ")
- )
- }
- Enter-key
- {
- (newline-and-indent)(n (current-column))
- (if (looking-at '\ *$') ; white space to end of line
- {
- (insert-text "}")
- (beginning-of-line)(open-line)
- })
- (to-col (+ n indent-level))
- }
- default (exe-key key)
- )
- }
- after-declare ; properly indent after a var declare
- {
- (newline-and-indent)(beginning-of-line)(open-line)
- (forward-line 1)(end-of-line)
- }
- )
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;; Comment mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (defun
- Dr.commento ; handle "/" & start up comment mode if need be
- {
- (int key col)
-
- (insert-text "/")(update)
- ;; Check to see if starting a comment. No "*" => no comment
- (if (!= (key (get-key)) 0x2A) { (exe-key key)(done) } )
- ;; check to see if this is a comment block
- (insert-text "*")
- (col (current-column))(beginning-of-line)
- (if (not (looking-at '\ */\*\ *$')) ; ws/*ws
- { ; its not a comment block - give them "/* */"
- (current-column col)
- (if (looking-at '\ *$') ; only if at end of line
- { (insert-text " */")(arg-prefix 3)(previous-character) } )
- (done)
- })
- (current-column col) ;; move back to where we started
- (insert-text " ") ;; make it look like "/* "
- (start-block-comment col)
- }
- Nurse-commento ;; Reenter block comment mode
- {
- (int col)
-
- (col (current-column))(beginning-of-line)
- (if (or
- (looking-at '\ *\*') ;; [ws]*
- (looking-at '\ */\*')) ;; [ws]/*
- {
- (search-forward '*')
- (start-block-comment (current-column))
- (if (looking-at '.*\*/') ;; [stuff]*/
- {
- (msg 'Notice that trailing "*/"!')
- })
- }
- {
- (msg "Not in a block comment!")
- })
- (current-column col)
- }
- start-block-comment (int col) HIDDEN ;; turn on block comment mode
- {
- (buffer-var "comment-offset" (- col 2))
- (word-wrap comment-wrap-column)
-
- (bind-local-key "Dr.CR" "C-m")
- (bind-local-key "C-mode-/" "/")
- (bind-local-key "nocomment" "M-;")
- (minor-mode "Dr. Commento")
- }
- nocomment ;; Turn off comment mode
- {
- (bind-local-key enter-key-action "C-m")
- (bind-local-key "Dr.commento" "/")
- (bind-local-key "Nurse-commento" "M-;")
-
- (minor-mode "")
- (word-wrap 0)
- }
- Dr.CR ;; handle Enter while in comment mode
- {
- (open-line)(beginning-of-line)
- ;; Note: save ws after *'s so can preserve indent.
- (if (looking-at '\ *.\ *\*+\(\ *\)') ; [ws]/*[ws] | ws*[*...][ws]
- {
- (forward-line 1)
- (to-col (buffer-var "comment-offset"))
- (insert-text c-stars (get-matched '\1')) ;; match prev indent
- }
- { ;; probably should handle this case better
- (forward-line 1)
- (msg "Your not in a comment block!")
- })
- }
- C-mode-/ ;; handle "/" in comment mode
- {
- (int col)
-
- (col (current-column))
- (previous-character)
- (if (looking-at '\*') ;; "*/" => ending comment
- { (nocomment)(goto ick) })
- (beginning-of-line)
- (if (looking-at '\ *\*+\ *$') ;; [ws]*[*...][ws]/
- {
- (current-column (buffer-var "comment-offset"))
- (cut-line)
- (insert-text comet)
- (nocomment)
- (done)
- })
- (label ick)
- (current-column col)(insert-text "/")
- }
- )
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;; Format block comment ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (defun
- add-stars (int n) HIDDEN
- {
- (int j)
-
- (j (+ n 1))
- (while (!= 0 (-= j 1)) (insert-text "*"))
- }
- format-C-comment
- {
- (bool start-comment end-comment boxed-comment)
- (int offset j)
- (int code-buffer scrbuf bag-id)
-
- (boxed-comment (arg-flag))
-
- (start-comment (end-comment FALSE))
-
- (code-buffer (current-buffer))
- (delete-region-as-block)
-
- (current-buffer (scrbuf (create-buffer scratch-buffer)))
-
- (insert-bag CUT-BUFFER)
-
- (beginning-of-buffer)
- (if (re-search-forward '^\ */\*') ; ^[ws]/*
- {
- (start-comment TRUE)
- (offset (- (current-column) 2))
- (beginning-of-line)
- (re-search-replace '^\ */\*+' "") ; get rid of ^[ws]/*[*...]
- }
- {
- (if (search-forward c-stars)
- (offset (- (current-column) 2))
- {
- ; else get the block offset from left margin
- (beginning-of-line)
- (while (is-space) (next-character))
- (offset (current-column))
- }
- )
- }
- )
-
- (beginning-of-buffer)
- (if (re-search-forward '\*/\ *$') ; */[ws]$
- {
- (end-comment TRUE)
- (beginning-of-line)
- (re-search-replace '\ *\*+/\ *$' "") ; get rid of [ws]*[*...]/[ws]$
- })
- (beginning-of-buffer)
- (re-search-replace '^\ *\*+' "") ; get rid of [white-space]*[*...]
-
- (beginning-of-buffer)
- (re-search-replace '\ *\*+$' "") ; get rid of [white-space]*[*...]$
-
- (msg "Formatting comment ...")
- (beginning-of-buffer)
- (adjust-lines
- 10000
- (- comment-wrap-column offset 1
- (if boxed-comment
- (+ (length-of boxed-comment-edge-stars)
- boxed-comment-trailing-blanks)
- 0
- ))
- FALSE
- )
- (beginning-of-buffer)
-
- ; put /*, * and */ in front of text
- (if start-comment
- {
- (to-col offset)(insert-text '/*')
- (if boxed-comment
- {
- (if (not (looking-at '\ *$')) (open-line))
- (add-stars (- comment-wrap-column (current-column)))
- (insert-text boxed-comment-edge-stars)
- (j boxed-comment-space)
- (while (<= 0 (-= j 1))
- {
- (newline-and-indent)(insert-text c-stars)
- (to-col comment-wrap-column)(insert-text boxed-comment-edge-stars)
- })
- })
- (forward-line 1)
- })
- (while (not (EoB))
- {
- (if (looking-at '^$')
- { (arg-prefix 1)(cut-line)(continue) } ; remove blank lines
- { ; else prepend *
- (to-col offset)(insert-text c-stars)
- (if boxed-comment
- {
- (end-of-line) (to-col comment-wrap-column)
- (insert-text boxed-comment-edge-stars)
- })
- }
- )
- (forward-line 1)
- })
- (if end-comment
- {
- (to-col offset)
- (if boxed-comment
- {
- (j boxed-comment-space)
- (while (<= 0 (-= j 1))
- {
- (insert-text c-stars)
- (to-col comment-wrap-column)(insert-text boxed-comment-edge-stars)
- (newline)(to-col offset)
- })
- (insert-text c-stars)
- (add-stars (- comment-wrap-column (current-column)))
- (insert-text boxed-comment-edge-stars "/")
- }
- (insert-text comet)
- )
- })
-
- ;; replace comment
- (beginning-of-buffer)(set-mark)(end-of-buffer)
- (append-to-bag (bag-id (create-bag)) APPEND-REGION)
-
- (msg "Comment formatted.")
-
- (current-buffer code-buffer)
- (insert-bag bag-id)
-
- ; clean up
- (free-buffer scrbuf)(free-bag bag-id)
- }
- )
-